#include "syntax_parser.h"
#include "errors_warnings.h"


#include "main_container.h"
extern MainContainer * CompilerData;


// <expression> ~ <expression2> <expression_adds>  {!, -, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
		currentUnit.type == LUTypeOperator &&
			(
				   currentUnit.subtype == OperatorNot
				|| currentUnit.subtype == OperatorSubtraction
				|| currentUnit.subtype == OperatorAddition
			)

		|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
		|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
		|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
		|| (currentUnit.type == LUTypeIdentifier)
		|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression__Expression2_ExpressionAdds production.");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression__Expression2_ExpressionAdds;

		// process nonterminal symbol <expression2> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression2(newNode0);

		// process nonterminal symbol <expression_adds> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_ExpressionAdds(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression");
#endif
}





// <expression_adds> ~ <expression_add> <expression_adds>  {||}
// <expression_adds> ~ ? {,, ;, ),:, +-, forming, units, {, simulations, ], NAME, after, every, send, while, until,}}
void Parser::Parse_ExpressionAdds(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_ExpressionAdds");
#endif
	LexicUnit currentUnit;
	do
	{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
		
			currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr
		)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"||\"");
#endif
			// write type of production in this node
			parent->Production = Gr_ExpressionAdds__ExpressionAdd_ExpressionAdds;

			// process nonterminal symbol <expression_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_ExpressionAdd(newNode0);

		}

		else if(
		
			(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma) 
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) 
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon) 
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUnits) 
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace) 
						|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSimulations) 
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightSquareBracket)
			|| (currentUnit.type == LUTypeIdentifier) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized epsilon part od production.");
#endif
			// write type of production in this node
			parent->Production = Gr_ExpressionAdds__ExpressionAdd_ExpressionAdds;
			break;

		}


		else
		{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error. Recovery is to skip this lexic unit.");
#endif
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ExpressionAdds");
#endif
}


// <expression_add> ~ || <expression2>  {||}
void Parser::Parse_ExpressionAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_ExpressionAdd");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"||\"");
#endif
		// write type of production in this node
		parent->Production = Gr_ExpressionAdd__opOr_Expression2;

		// process terminal symbol '||' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression2> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression2(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ExpressionAdd");
#endif
}


// <expression2> ~ <expression3> <expression2_adds>  {!, -, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression2(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression2");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorNot
						|| currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression2__Expression3_Expression2Adds production.");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression2__Expression3_Expression2Adds;

		// process nonterminal symbol <expression3> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression3(newNode0);

		// process nonterminal symbol <expression2_adds> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression2Adds(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression2");
#endif
}




// <expression2_adds> ~ <expression2_add> <expression2_adds>  {^^}
// <expression2_adds> ~ ? {||, ,, ;,:, ), +-, forming, units, {, simulations, ], NAME, after, every, send, while, until,}}
void Parser::Parse_Expression2Adds(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression2Adds");
#endif
	LexicUnit currentUnit;
	
	do{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
				currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorXor
		)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"^^\"");
#endif
			// write type of production in this node
			parent->Production = Gr_Expression2Adds__Expression2Add_Expression2Adds;

			// process nonterminal symbol <expression2_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_Expression2Add(newNode0);

		}

		else if(
		
			(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUnits)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace) || (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSimulations)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightSquareBracket)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type ==  LUTypeKeyword && currentUnit.subtype == KeywordAfter)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized epsilon part od production.");
#endif
			// write type of production in this node
			parent->Production = Gr_Expression2Adds__Expression2Add_Expression2Adds;
			break;
		}


		else
		{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error. Recovery is to skip this lexic unit.");
#endif			
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression2Adds");
#endif
}




// <expression2_add> ~ ^^ <expression3>  {^^}
void Parser::Parse_Expression2Add(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression2Add");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
		currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorXor
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"^^\"");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression2Add__opXor_Expression3;

		// process terminal symbol '^^' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression3> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression3(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression2Add");
#endif
}


// <expression3> ~ <expression4> <expression3_adds>  {!, -, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression3(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression3");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
			currentUnit.type == LUTypeOperator &&
				(
					   currentUnit.subtype == OperatorNot
					|| currentUnit.subtype == OperatorSubtraction
					|| currentUnit.subtype == OperatorAddition
				)

			|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
		)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression3__Expression4_Expression3Adds production.");
#endif

		// write type of production in this node
		parent->Production =Gr_Expression3__Expression4_Expression3Adds;

		// process nonterminal symbol <expression4> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression4(newNode0);

		// process nonterminal symbol <expression3_adds> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression3Adds(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression3");
#endif
}


// <expression3_adds> ~ <expression3_add> <expression3_adds>  {&&}
// <expression3_adds> ~ ? {^^, ||, ,, ;,:, ), +-, forming, units, {, simulations, ], NAME, after, every, send, while, until,}}
void Parser::Parse_Expression3Adds(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression3Adds");
#endif
	LexicUnit currentUnit;
	do{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
		
			currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAnd
		)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"&&\"");
#endif
			// write type of production in this node
			parent->Production = Gr_Expression3Adds__Expression3Add_Expression3Adds;

			// process nonterminal symbol <expression3_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_Expression3Add(newNode0);


		}

		else if(
		
			(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorXor)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUnits)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace)|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSimulations)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightSquareBracket)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized epsilon part od production.");
#endif
			// write type of production in this node
			parent->Production =Gr_Expression3Adds__Expression3Add_Expression3Adds;
			break;

		}


		else
		{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error. Recovery is to skip this lexic unit.");
#endif
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
		// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression3Adds");
#endif
}



// <expression3_add> ~ && <expression4>  {&&}
void Parser::Parse_Expression3Add(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression3Add");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAnd)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"&&\"");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression3Add__opAnd_Expression4;

		// process terminal symbol '&&' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression4> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression4(newNode1);
	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression3Add");
#endif
}

// <expression4> ~ <expression5>  {-, +, LITERAL, null, new, NAME, (}
// <expression4> ~ ! <expression4>  {!}
void Parser::Parse_Expression4(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression4");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression4__Expression5 production.");
#endif

		// write type of production in this node
		parent->Production =Gr_Expression4__Expression5;

		// process nonterminal symbol <expression5> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression5(newNode0);

	}

	else if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNot)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"!\"");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression4__opNot_Expression4;

		// process terminal symbol '!' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression4> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression4(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression4");
#endif
}




// <expression5> ~ <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> < <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> > <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> <= <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> >= <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> == <expression6>  {-, +, LITERAL, null, new, NAME, (}
// <expression5> ~ <expression6> != <expression6>  {-, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression5(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression5");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
		
		// process nonterminal symbol <expression6> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression6(newNode0);

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// now we must determine which one is right production
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if( (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan) )
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"<\"");
#endif
			parent->Production =Gr_Expression5__Expression6_opLess_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);			
		}
		else if(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThan)
		{
			parent->Production =Gr_Expression5__Expression6_opGreat_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);
		}
		else if( currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThanOrEqualTo)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"<=\"");
#endif
			parent->Production =Gr_Expression5__Expression6_opLessEq_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);
		}
		else if( currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThanEqualTo) 
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \">=\"");
#endif
			parent->Production =Gr_Expression5__Expression6_opGreatEq_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
			
			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);			
		}
		else if(currentUnit.type ==LUTypeOperator && currentUnit.subtype == OperatorEqual)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"=\"");
#endif
			parent->Production =Gr_Expression5__Expression6_opEq_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);
		}
		else if(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNotEqual)
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"!=\"");
#endif
			parent->Production =Gr_Expression5__Expression6_opNotEq_Expression6;
			
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression6> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression6(newNode2);
			
		}
		else
		{
			parent->Production =Gr_Expression5__Expression6;
		}
	}

	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression5");
#endif
}


// <expression6> ~ <expression7> <expression6_adds>  {-, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression6(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression6");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression6__Expression7_Expression6Adds production.");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression6__Expression7_Expression6Adds;

		// process nonterminal symbol <expression7> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression7(newNode0);

		// process nonterminal symbol <expression6_adds> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression6Adds(newNode1);
	}
	else
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Error.");
#endif

	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression6");
#endif
}


// <expression6_adds> ~ <expression6_add> <expression6_adds>  {+, -}
// <expression6_adds> ~ ? {<, >, <=, >=, ==, !=, &&, ^^, ||, ,, ;, ), +-, forming, units, {, simulations, ], NAME, after, every, send, while, until,}}
void Parser::Parse_Expression6Adds(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression6Adds");
#endif
	LexicUnit currentUnit;
	
	do
	{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(
		
			currentUnit.type == LUTypeOperator &&
						(
							currentUnit.subtype == OperatorSubtraction
							|| currentUnit.subtype == OperatorAddition
						)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression6Adds__Expression6Add_Expression6Adds production.");
#endif
			// write type of production in this node
			parent->Production =Gr_Expression6Adds__Expression6Add_Expression6Adds;

			// process nonterminal symbol <expression6_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_Expression6Add(newNode0);

		}

		else if(
		
			(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThan) 
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThanOrEqualTo)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThanEqualTo)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorEqual)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNotEqual)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAnd)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorXor)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUnits)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace)|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSimulations)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightSquareBracket)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized epsilon part od production.");
#endif
			// write type of production in this node
			parent->Production = Gr_Expression6Adds__Expression6Add_Expression6Adds;
			break;

		}


		else
		{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error. Recovery is to skip this lexic unit.");
#endif

		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
		// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;

		}
	}
	while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression6Adds");
#endif
}

// <expression6_add> ~ + <expression7>  {+}
// <expression6_add> ~ - <expression7>  {-}
void Parser::Parse_Expression6Add(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression6Add");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif

	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		 (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAddition)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"+\"");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression6Add__opAdd_Expression7;

		// process terminal symbol '+' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression7> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression7(newNode1);

	}

	else if(
	
		 (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorSubtraction)
	)
	{

#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"-\"");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression6Add__opSub_Expression7;

		// process terminal symbol '-' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression7> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression7(newNode1);


	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);

	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression6Add");
#endif
}


// <expression7> ~ <expression8> <expression7_adds>  {-, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression7(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression7");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif

	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression7__Expression8_Expression7Adds production.");
#endif

		// write type of production in this node
		parent->Production =Gr_Expression7__Expression8_Expression7Adds;

		// process nonterminal symbol <expression8> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression8(newNode0);

		// process nonterminal symbol <expression7_adds> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression7Adds(newNode1);
	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);

	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression7");
#endif
}


// <expression7_adds> ~ <expression7_add> <expression7_adds>  {*, /, %}
// <expression7_adds> ~ ? {+, -, <, >, <=, >=, ==, !=, &&, ^^, ||, ,, ;, :,), +-, forming, units, {, simulations, ], NAME, after, every, send, while, until,}}
void Parser::Parse_Expression7Adds(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression7Adds");
#endif

	LexicUnit currentUnit;
	
	
	do
	{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif

		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if(
		
			(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorMultiplication)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorDivision) 
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorModulus)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression7Adds__Expression7Add_Expression7Adds production.");
#endif
			// write type of production in this node
			parent->Production =Gr_Expression7Adds__Expression7Add_Expression7Adds;

			// process nonterminal symbol <expression7_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_Expression7Add(newNode0);


		}

		else if(
		
			(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAddition)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorSubtraction)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThan)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThan)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorLessThanOrEqualTo)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorGreaterThanEqualTo)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorEqual)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNotEqual)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAnd)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorXor)
			|| (currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorOr)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUnits)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace)	|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) 
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSimulations)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightSquareBracket)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil)
		)
		{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized epsilon part od production.");
#endif
			// write type of production in this node
			parent->Production =Gr_Expression7Adds__Expression7Add_Expression7Adds;
			break;

		}


		else
		{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error. Recovery is to skip this lexic unit.");
#endif
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);

		// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;

		}
	}
	while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression7Adds");
#endif
}


// <expression7_add> ~ * <expression8>  {*}
// <expression7_add> ~ / <expression8>  {/}
// <expression7_add> ~ % <expression8>  {%}
void Parser::Parse_Expression7Add(SyntaxTreeNode * parent)
{
#ifdef TRACE
    CompilerData->LogTrace->ReportEntry("Parse_Expression7Add");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif

	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorMultiplication)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"*\"");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression7Add__opMul_Expression8;

		// process terminal symbol '*' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression8> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression8(newNode1);

	}

	else if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorDivision)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"/\"");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression7Add__opDiv_Expression8;

		// process terminal symbol '/' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression8> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression8(newNode1);

	}

	else if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorModulus)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"%\"");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression7Add__opMod_Expression8;

		// process terminal symbol '%' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression8> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression8(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression7Add");
#endif
}


// <expression8> ~ <expression9>  {-, +, LITERAL, null, new, NAME, (}
// <expression8> ~ <expression9> ^ <expression8>  {-, +, LITERAL, null, new, NAME, (}
void Parser::Parse_Expression8(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Expression8");
#endif
	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
		currentUnit.type == LUTypeOperator &&
					(
						   currentUnit.subtype == OperatorSubtraction
						|| currentUnit.subtype == OperatorAddition
					)

				|| (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
				|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
				|| (currentUnit.type == LUTypeIdentifier)
				|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
			
	)
	{
		// process nonterminal symbol <expression9> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression9(newNode0);


#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
		// process terminal symbol '^' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if((currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorExponentiation))
		{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"^\"");
#endif
			// write type of production in this node
			parent->Production =Gr_Expression8__Expression9_opExp_Expression8;

			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <expression8> 
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			Parse_Expression8(newNode2);

		}
		else
		{
			// write type of production in this node
			parent->Production =Gr_Expression8__Expression9;
		}


	}
	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif

	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression8");
#endif
}

// <expression9> ~ <value>  {LITERAL, null, new, NAME, (}
// <expression9> ~ - <expression9>  {-}
// <expression9> ~ + <expression9>  {+}
void Parser::Parse_Expression9(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Expression9");
#endif


	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif

	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(
	
			   (currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull)
			|| (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew)
			|| (currentUnit.type == LUTypeIdentifier)
			|| (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)

	)
	{
#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Recognized Gr_Expression9__Value production.");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression9__Value;

		// process nonterminal symbol <value> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Value(newNode0);

	}

	else if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorSubtraction)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"-\"");
#endif
		// write type of production in this node
		parent->Production =Gr_Expression9__opSub_Expression9;

		// process terminal symbol '-' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression9> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression9(newNode1);

	}

	else if(
	
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAddition)
	)
	{
#ifdef TRACE
		CompilerData->LogTrace->ReportLine("Recognized operator \"+\"");
#endif
		// write type of production in this node
		parent->Production = Gr_Expression9__opAdd_Expression9;

		// process terminal symbol '+' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <expression9> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression9(newNode1);

	}


	else
	{
#ifdef TRACE
	        CompilerData->LogTrace->ReportLine("Error.");
#endif
	// ERROR has been found
	// REPORT ERROR
	CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_CLASS_BODY_MATCH);
	// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Expression9");
#endif
}
